/*
 * Copyright (C) 2022 xuexiangjys(xuexiangjys@163.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.xjh.him.adapter;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.FutureTarget;
import com.scwang.smartrefresh.layout.adapter.SmartViewHolder;
import com.xjh.him.R;
import com.xjh.him.adapter.entity.ChatMessage;
import com.xjh.him.core.WeChatPresenter;
import com.xjh.him.utils.Utils;
import com.xuexiang.xutil.display.DensityUtils;
import com.ypx.imagepicker.ImagePicker;
import com.ypx.imagepicker.bean.ImageItem;
import com.ypx.imagepicker.data.OnImagePickCompleteListener;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;


public class ChatAdapter extends RecyclerView.Adapter<SmartViewHolder> {
    private static final int CHAT_LEFT_TEXT_ITEM = 1;
    private static final int CHAT_LEFT_IMAGE_ITEM = 2;
    private static final int CHAT_LEFT_AUDIO_ITEM = 3;
    private static final int CHAT_RIGHT_TEXT_ITEM = 4;
    private static final int CHAT_RIGHT_IMAGE_ITEM = 5;
    private static final int CHAT_RIGHT_AUDIO_ITEM = 6;
    private static final int CHAT_USER_INVITE = 7;


    /**
     * 是否展示消息时间的阈值
     *
     * 当前消息和上一条消息时间间隔小于等于1小时，则不展示本条消息的时间
     */
    private static final int SHOW_CHAT_TIME_THRESHOLD = 3600 * 1000;

    private Activity mActivity;
    private List<ChatMessage> items;

    public ChatAdapter(Activity activity, List<ChatMessage> items) {
        this.items = items;
        this.mActivity = activity;
    }

    @NonNull
    @Override
    public SmartViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        int resId = 0;
        switch (viewType) {
            case CHAT_LEFT_TEXT_ITEM:
                resId = R.layout.adapter_left_text_msg;
                break;
            case CHAT_LEFT_IMAGE_ITEM:
                resId = R.layout.adapter_left_image_msg;
                break;
            case CHAT_LEFT_AUDIO_ITEM:
                break;
            case CHAT_RIGHT_TEXT_ITEM:
                resId = R.layout.adapter_right_text_msg;
                break;
            case CHAT_RIGHT_IMAGE_ITEM:
                resId = R.layout.adapter_right_image_msg;
                break;
            case CHAT_RIGHT_AUDIO_ITEM:
                break;
            case CHAT_USER_INVITE:
                resId = R.layout.adapter_user_invite;
                break;
        }
        View itemView = LayoutInflater.from(parent.getContext()).inflate(resId, parent, false);
        return new SmartViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull SmartViewHolder holder, int position) {
        ChatMessage chatMessage = items.get(position);
        if (holder.getItemViewType() == CHAT_USER_INVITE) {
            holder.text(R.id.tv_invite_tip, chatMessage.getInviteTip());
            return;
        }

        holder.text(R.id.chat_time, ChatMessage.DATE_FORMAT.format(chatMessage.getCreateTime()));
        holder.text(R.id.chatter_name, chatMessage.getSenderName());
        ImageView ivAvatar = holder.findViewById(R.id.chat_avatar);
        Utils.setImageViewParams(ivAvatar, 50, 50);
        Glide.with(mActivity)
                .load(chatMessage.getSenderAvatarUrl())
                .apply(Utils.getRoundedCornersRequestOptions(5))
                .into(ivAvatar);
        switch (items.get(position).getMsgType()) {
            case ChatMessage.TYPE_TEXT:
                holder.text(R.id.chat_text, chatMessage.getTextMsg());
                break;
            case ChatMessage.TYPE_IMAGE:
                //跳过表情图片
                if (chatMessage.getFileUrl() == null) {
                    holder.image(R.id.chat_image, Integer.parseInt(chatMessage.getTextMsg()));
                    break;
                }
                //图片
                ImageView imageView = holder.findViewById(R.id.chat_image);
                Glide.with(mActivity)
                        .load(chatMessage.getFileUrl())
                        .override(DensityUtils.getDisplayMetrics().widthPixels / 2)
                        .centerCrop()
                        .into(imageView);

                imageView.setOnClickListener(v -> {
                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
                        List<ChatMessage> imageMsgList = items.stream()
                                .filter(msg -> msg.getMsgType().equals(ChatMessage.TYPE_IMAGE) && msg.getFileUrl() != null)
                                .collect(Collectors.toList());

                        int selectPosition = 0;
                        ArrayList<String> pathList = new ArrayList<>();
                        CountDownLatch latch = new CountDownLatch(imageMsgList.size());
                        for (int i = 0; i < imageMsgList.size(); i++) {
                            ChatMessage msg = imageMsgList.get(i);
                            new Thread(() -> {
                                try {
                                    FutureTarget<File> futureTarget = Glide.with(mActivity)
                                            .downloadOnly()
                                            .load(msg.getFileUrl())
                                            .submit();
                                    File file = futureTarget.get();
                                    if (file != null) {
                                        pathList.add(file.getAbsolutePath());
                                    }
                                } catch (InterruptedException | ExecutionException e) {
                                    e.printStackTrace();
                                } finally {
                                    latch.countDown();
                                }
                            }).start();
                            if (msg.getFileUrl().equals(chatMessage.getFileUrl())) {
                                selectPosition = i;
                            }
                        }

                        try {
                            latch.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        ImagePicker.preview(mActivity, new WeChatPresenter(), pathList, selectPosition, new OnImagePickCompleteListener() {
                            @Override
                            public void onImagePickComplete(ArrayList<ImageItem> items) {

                            }
                        });
                    }
                });
                break;
            case ChatMessage.TYPE_AUDIO:
                break;
        }

        if (invisibleChatTime(position, chatMessage)) {
            holder.visible(R.id.chat_time, View.GONE);
        }else {
            holder.visible(R.id.chat_time, View.VISIBLE);
        }
        holder.visible(R.id.chat_send_failed_icon, View.GONE);
        holder.visible(R.id.chat_progress_bar, View.GONE);
    }

    private boolean invisibleChatTime(int position, ChatMessage chatMessage) {
        return position > 0 && chatMessage.getCreateTime().getTime() -
                items.get(position-1).getCreateTime().getTime() <= SHOW_CHAT_TIME_THRESHOLD;
    }

    @Override
    public int getItemCount() {
        return items.size();
    }

    @Override
    public int getItemViewType(int position) {
        int viewType = 0;
        ChatMessage chatMessage = items.get(position);
        if (ChatMessage.TYPE_USER_INVITE.equals(chatMessage.getMsgType())) {
            return CHAT_USER_INVITE;
        }
        if (chatMessage.getItemDirection().equals(ChatMessage.DIRECTION_LEFT)) {
            switch (chatMessage.getMsgType()) {
                case ChatMessage.TYPE_TEXT:
                    viewType = CHAT_LEFT_TEXT_ITEM;
                    break;
                case ChatMessage.TYPE_IMAGE:
                    viewType = CHAT_LEFT_IMAGE_ITEM;
                    break;
                case ChatMessage.TYPE_AUDIO:
                    viewType = CHAT_LEFT_AUDIO_ITEM;
                    break;
            }
        }else {
            switch (chatMessage.getMsgType()) {
                case ChatMessage.TYPE_TEXT:
                    viewType = CHAT_RIGHT_TEXT_ITEM;
                    break;
                case ChatMessage.TYPE_IMAGE:
                    viewType = CHAT_RIGHT_IMAGE_ITEM;
                    break;
                case ChatMessage.TYPE_AUDIO:
                    viewType = CHAT_RIGHT_AUDIO_ITEM;
                    break;
            }
        }
        if (viewType == 0) {
            throw new IllegalStateException("未知消息类型");
        }
        return viewType;
    }

    public List<ChatMessage> listData() {
        return this.items;
    }
}
